package vn.edu.thptduongbachmai.common;

import com.googlecode.htmlcompressor.compressor.HtmlCompressor;
import com.vng.zing.exception.InvalidParamException;
import com.vng.zing.exception.NotExistException;
import com.vng.zing.logger.ZLogger;
import hapax.Template;
import hapax.TemplateDataDictionary;
import hapax.TemplateDictionary;
import hapax.TemplateException;
import hapax.TemplateLoader;
import hapax.TemplateResourceLoader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.json.simple.JSONValue;

/**
 *
 * @author tiennv4
 */
public class TemplateManager {

    private static final Logger _Logger = ZLogger.getLogger(TemplateManager.class);
    private static ConcurrentMap<String, TemplateLoader> _InstMap = new ConcurrentHashMap<String, TemplateLoader>();
    private static String PATH_LAYOUT = "vn/edu/thptduongbachmai/view/admin/";
    private static String PATH_VIEW = "vn/edu/thptduongbachmai/view/admin/page/";
    private static String LAYOUT = "layout";

    public static TemplateLoader getTemplateLoader(String baseDir) {
        assert (baseDir != null);
        String key = baseDir.trim();
        TemplateLoader ret = _InstMap.get(key);
        if (ret == null) {
            ret = TemplateResourceLoader.create(key);
            TemplateLoader old = _InstMap.putIfAbsent(key, ret);
            if (old != null) {
                ret = old;
            }
        }
        return ret;
    }

    public static Template getTemplate(String tplName) throws TemplateException {
        TemplateLoader temploader = TemplateManager.getTemplateLoader("view/");
        return temploader.getTemplate(tplName);
    }

    public static Template getTemplate(String baseDir, String tplName) throws TemplateException {
        TemplateLoader temploader = getTemplateLoader(baseDir);
        return temploader.getTemplate(tplName);
    }

    public static Template getTemplateJsonCompressed(String baseDir, String tplName) throws TemplateException {
        TemplateLoader temploader = getTemplateLoader(baseDir);
        Template tpl = temploader.getTemplateFromString(tplName);
        if (tpl == null) {
            String tpl_data;
            try {
                tpl_data = temploader.getTplData(tplName);
                if (tpl_data == null) {
                    return null;
                }
                HtmlCompressor compressor = new HtmlCompressor();
                tpl_data = compressor.compress(tpl_data);
                tpl_data = JSONValue.toJSONString(tpl_data);
                tpl = temploader.getTemplateFromString(tplName, tpl_data);
            } catch (Exception ex) {
                _Logger.error(null, ex);
                return null;
            }

        }
        return tpl;
    }

    public static String applyTemplate(TemplateDataDictionary dic) throws TemplateException {
        Template template = getTemplate(PATH_LAYOUT, LAYOUT);
        return template.renderToString(dic);
    }

    public static void view(HttpServletResponse resp, TemplateDataDictionary dic) {
        try {
            print(applyTemplate(dic), resp);
        } catch (TemplateException ex) {
            _Logger.error(ex.getMessage(), ex);
        } catch (Exception ex) {
            _Logger.error(ex.getMessage(), ex);
        }
    }

    public static String applyTemplate(TemplateDataDictionary dic, String tplName) {
        try {
            Template template = getTemplate(PATH_VIEW, tplName);
            dic.setVariable("static_domain", Configuration.APP_STATIC_DOMAIN);
            return template.renderToString(dic);
        } catch (Exception ex) {
            _Logger.error(ex, ex);
        }
        return null;
    }

    public static String applyTemplate(TemplateDataDictionary dic, HttpServletRequest req) throws TemplateException, NotExistException, InvalidParamException {
        Template template = getTemplate(PATH_VIEW, LAYOUT);
        if (template != null) {
            dic.setVariable("static_domain", Configuration.APP_STATIC_DOMAIN);
            return template.renderToString(dic);
        }
        return "";
    }

    /**
     * prepareHeaderHtml: set http header for html content (text/html;
     * charset=UTF-8)
     *
     * @param resp
     */
    public static void prepareHeaderHtml(HttpServletResponse resp) {
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html; charset=UTF-8");
    }

    public static void prepareHeaderFavicon(HttpServletResponse resp) {
        resp.setContentType("text/plain; charset=WINDOWS-1251");
    }

    /**
     * prepareHeaderJs: set http header for javascript content (text/javascript;
     * charset=UTF-8)
     *
     * @param resp
     */
    public static void prepareHeaderJs(HttpServletResponse resp) {
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/javascript; charset=UTF-8");
    }

    public static void printFavicon(Object obj, HttpServletResponse resp) {
        PrintWriter out = null;
        try {
            prepareHeaderFavicon(resp);
            out = resp.getWriter();
            out.print(obj);
        } catch (IOException ex) {
            _Logger.error(ex.getMessage(), ex);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    //send the final HTML string result to respone
    public static void print(Object obj, HttpServletResponse resp) {
        PrintWriter out = null;
        try {
            prepareHeaderHtml(resp);
            out = resp.getWriter();
            out.print(obj);
        } catch (IOException ex) {
            _Logger.error(ex.getMessage(), ex);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    public static void printJSON(Object json, HttpServletResponse resp) {
        PrintWriter out = null;
        try {
            resp.setContentType("application/json;charset=UTF-8");
            out = resp.getWriter();
            out.print(json);
        } catch (IOException ex) {
            _Logger.error(ex.getMessage(), ex);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    public static void printf(String str, HttpServletResponse resp) {
        PrintWriter out = null;
        try {
            prepareHeaderHtml(resp);
            out = resp.getWriter();
            out.println(str);
        } catch (Exception e) {
            _Logger.error(e.getMessage(), e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    //Get info for layout template
    public static TemplateDataDictionary getDictionary() throws NotExistException, InvalidParamException {
        TemplateDataDictionary dic = TemplateDictionary.create();
        dic.setVariable("domain", Configuration.APP_DOMAIN);
        dic.setVariable("static_domain", Configuration.APP_STATIC_DOMAIN);
        return dic;
    }
}
